import os
from django.db import models

from assets.models import LOG


from django.contrib.auth.models import User

from favorites.managers import FavoritesManagerMixin


class FormatTypeManager(models.Manager):
  def get_by_natural_key(self, name):
    return self.get(name=name)
    
class FormatManager(models.Manager):
  def get_by_natural_key(self, name, type):
    return self.get(name=name)

class AssetQuerySet(models.query.QuerySet):
  def __init__(self, *args, **kwargs):
    super(AssetQuerySet, self).__init__(*args, **kwargs)
  """
  def get(self, *args, **kwargs):
    from assets.models import UUIDLookup
    if 'id' in kwargs:
      try:
        u = UUIDLookup.objects.get(old=kwargs['id'])
        while u.new:
          u = u.new
        kwargs['id'] = u.old
      except UUIDLookup.DoesNotExist:
        pass
    return super(AssetQuerySet, self).get(*args, **kwargs)
  """
    
class AssetManager(models.Manager, FavoritesManagerMixin):
  def get_query_set(self):
    return AssetQuerySet(self.model)
    
  def get(self, *args, **kwargs):
    return self.get_query_set().get(*args, **kwargs)

  def get_or_create(self, *args, **kwargs):
    from assets.models import Asset
    try:
      a = super(AssetManager, self).get(*args, **kwargs)
      return a, False
    except Asset.DoesNotExist:
      if 'file' in kwargs:
        file= kwargs['file']
        if not 'id' in kwargs:
          import hashlib
          kwargs['id'] = hashlib.sha1(file.hash + str(kwargs['subName']) + str(kwargs['format'].name)).hexdigest()
        a = super(AssetManager, self).create(*args, **kwargs)
        a.save()
        return a, True

  def get_or_create_from(self, anAssetReference, i=0):
    from assets.models import Asset, File, Format, MetaData
    LOG.info(" "*i+"Fetching/Creating DB Asset %s - %s - %s:", anAssetReference.id, anAssetReference.subName, anAssetReference.format)
    try:
      a = Asset.objects.get(id=anAssetReference.id)
      created = False
      file =  a.file
    except Asset.DoesNotExist:
      LOG.info(" "*i+" Fetching by id failed %s - %s - %s trying...", anAssetReference.id, anAssetReference.subName, anAssetReference.format)
      file, c = File.objects.get_or_create_from(anAssetReference.file)
      file.save()  
      if anAssetReference.brokenReference:
        pass #TODO
      format, c = Format.objects.get_or_create(name=anAssetReference.format)
      format.save()
      a, created = self.get_or_create(file=file, subName=anAssetReference.subName, format=format)
      if not created:
        LOG.info("UPDATED ASSET")
        """
        if a.id != anAssetReference.id:
          #Asset id might have changed at this point, store in lookup table!
          n,c = UUIDLookup.objects.get_or_create(old=anAssetReference.id, new=None)
          n.save()
          o,c = UUIDLookup.objects.get_or_create(old=a.id, new=n)
          o.save()
        """
        #Finally update id
        a.id = anAssetReference.id

    LOG.info(" "*i+"Succesfully '%s' DB Asset %s.", 'created' if created else 'fetched', a.id)
    
    LOG.info(" %s  <>  %s", anAssetReference.file.hash, a.file.hash)
    
    for k,v in anAssetReference.metaData.items():
      m, c = MetaData.objects.get_or_create(asset=a, name=k)
      m.SetValue(v)
      m.save()
    if len(anAssetReference.dependencies): LOG.info(" "*i+"Dependencies:")
    for dep in anAssetReference.dependencies:
      d, c = Asset.objects.get_or_create_from(dep, i+2)
      a.dependencies.add(d)
    a.save()
    #TODO: clean out old dependencies and metadata?
    return a, created

  def get_reference(self, *args, **kwargs):
    from damn import FileReference, AssetReference
    db = self.get(*args, **kwargs)
    fdb = db.file
    f = FileReference(fdb.location.path)
    f.brokenReference = fdb.filepath_set.count() == 0
    a = AssetReference(db.subName, db.format.name, f)
    a._id = db.id
    for dep in db.dependencies.all():
      d = self.get_reference(id=dep.id)
      a.AddDepency(d)
    #TODO: add metadata
    return a
